package com.ophelisis.actions.menuMgmt;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.swing.ImageIcon;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.ophelisis.common.consts.ConstCode;
import com.ophelisis.common.consts.ConstPath;
import com.ophelisis.common.core.AlmapFileRenamePolicy;
import com.ophelisis.common.util.FileUtil;
import com.ophelisis.common.util.UploadUtil;
import com.ophelisis.persistence.dao.LogoDAO;
import com.ophelisis.persistence.domain.LogoVO;
import com.oreilly.servlet.MultipartRequest;

/** <pre>
 * Class : com.ophelisis.actions.menuMgmt.LogoMgmt / LogoMgmt.java
 * 	Define Class Object : 
 * <br>
 * </pre>
 * @author hlee / apexcns,Inc.
 * @version 1.0
 * @see javadoc
 * @since 2013. 07. 29.
 */
@Controller
public class LogoMgmt {
	@Autowired
	LogoDAO logoDAO;
	
	private List<LogoVO> logoList;
	private String sResult = "";
	
	private Log log = LogFactory.getLog(this.getClass());
	private static final String _LogPrefixStr = "MenuMgmt Log> ";
	
	private String savePath = ConstPath.rootPath + "/logo/"; 
	private int maxPostSize = 10 * 1024 * 1024; // 10MB
	private static int thumbnail_width = 285;
	private static int thumbnail_height = 50;

	@RequestMapping(value="logoMgmt.action")
	public ModelAndView logoMgmt(
			HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam(value="target", defaultValue="lmMain") String sTarget,
			@RequestParam(value="_groupId", defaultValue="0") String sMenuGroupId,
			@RequestParam(value="_menuId", defaultValue="0") String sMenuId,
			@RequestParam(value="_menuType", defaultValue="1") String sMenuType,
			@RequestParam(value="_menuNm", defaultValue="") String sMenuNm,
			@RequestParam(value="_menuAuth", defaultValue="0") String sUserMenuAuth,
			@RequestParam(value="_prevUpCode", defaultValue="") String sPrevUpCode,
			@RequestParam(value="_prevCode", defaultValue="") String sPrevCode,
			@RequestParam(value="_startRowNo", defaultValue="0") String sStartRowNo,
			@RequestParam(value="_pageSize", defaultValue="15") String sPageSize,
			@RequestParam(value="currentLogoId", defaultValue="") String sCurrentLogoId,
			@RequestParam(value="isNew", defaultValue="Y") String isNew,
			@ModelAttribute LogoVO logoVO) throws Exception {
		ModelAndView mav = new ModelAndView();
		HttpSession session = request.getSession(false);

		log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		log.debug(_LogPrefixStr + "|" + " LogoMgmt called !!!");
		log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		
		try {
			// 공통 요소
			mav.addObject("_groupId", sMenuGroupId);
			mav.addObject("_menuId", sMenuId);
			mav.addObject("_menuType", sMenuType);
			mav.addObject("_menuNm", sMenuNm);
			mav.addObject("_menuAuth", sUserMenuAuth);
			mav.addObject("_prevUpCode", sPrevUpCode);
			mav.addObject("_prevCode", sPrevCode);
			mav.addObject("_startRowNo", sStartRowNo);
			mav.addObject("_pageSize", sPageSize);

			int iStartRowNo = Integer.parseInt(sStartRowNo); // 해당 페이지의 시작 번호
			int iPageSize = Integer.parseInt(sPageSize); // 한 페이지에 보일 레코드 수
			
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("menuGroupId", sMenuGroupId);
			params.put("menuId", sMenuId);
			params.put("menuType", sMenuType);
			params.put("startRowNo", iStartRowNo); // 공통 코드 그룹 ID (1:메뉴 유형)
			params.put("pageSize", iPageSize);
			params.put("logoId", sPrevCode);
			params.put("updateUser", (String)session.getAttribute("userId"));
			
			if (sTarget.equals("lmMain")) {
				mav = returnMgmt("main", mav, params);
			} else if (sTarget.equals("lmList")) {
				mav = returnMgmt("list", mav, params);
			} else if (sTarget.equals("lmDetail")) {
				mav = returnMgmt("detail", mav, params);
			} else if (sTarget.equals("lmViewImage")) {
				mav.addObject("fileName", logoVO.getLogoFileNew());
				mav.addObject("fileWidth", logoVO.getLogoFileWidth());
				mav.addObject("fileHeight", logoVO.getLogoFileHeight());
				mav.setViewName("/WEB-INF/jsp/menuMgmt/logoMgmtViewImage.jsp");
				
				log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
				log.debug(_LogPrefixStr + "|" + " LogoMgmt Image-View-Page called !!!");
				log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
			} else if (sTarget.equals("lmAdd")) {
				mav.setViewName("/WEB-INF/jsp/menuMgmt/logoMgmtAdd.jsp");
				
				log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
				log.debug(_LogPrefixStr + "|" + " LogoMgmt Add-Page called !!!");
				log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
			} else if (sTarget.equals("lmConfirm")) {
				logoVO.setLogoId(sPrevCode);
				logoVO.setUseYn("Y");
				logoDAO.setLogoModify(logoVO);

				if (!sCurrentLogoId.equals("")) {
					logoVO.setLogoId(sCurrentLogoId);
					logoVO.setUseYn("N");
					logoDAO.setLogoModify(logoVO);
				}

				mav = returnMgmt("list", mav, params);
			} else if (sTarget.equals("lmDelete")) {
				try {
					logoList = logoDAO.getLogoDetail(params);
					if (logoList != null && !logoList.isEmpty()) {
						String[] sFileName = logoList.get(0).getLogoFileNew().split("\\|");
						
						for (int i = 0; i < sFileName.length; i++) {
							FileUtil.pathFileDelete(savePath, sFileName[i]);
							FileUtil.pathFileDelete(savePath, ConstCode.thumbnailPrefix + sFileName[i]);
						}
					}
					
					sResult = logoDAO.setLogoDelete(params) > 0 ? "정상적으로 처리되었습니다." : "처리에 실패하였습니다.<BR/>관리자에게 문의하여 주십시오."; // 유저 정보 업데이트
				} catch (Exception e) {
					log.error("DB 정보 획득 failed!", e);
				}
				
				mav.addObject("result", sResult);
				
				mav = returnMgmt("list", mav, params);
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		return mav;
	}
	
	public ModelAndView returnMgmt(
			@RequestParam(value="cmd", defaultValue="list") String cmd,
			@ModelAttribute ModelAndView mav,
			Map<String, Object> params) throws Exception {
		if (cmd.equals("main")) {
			mav.setViewName("/WEB-INF/jsp/menuMgmt/logoMgmt.jsp");

			log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
			log.debug(_LogPrefixStr + "|" + " LogoMgmt Main-Page called !!!");
			log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		} else if (cmd.equals("list")) {
			int iTotalCount = 0;
			
			try {
				iTotalCount = logoDAO.getLogoListCnt(params); // 쿼리 결과 카운트
				logoList = logoDAO.getLogoList(params); // 쿼리 결과
			} catch (Exception e) {
				log.error("DB 정보 획득 failed!", e);
			}

			mav.addObject("totalCnt", String.valueOf(iTotalCount));
			mav.addObject("logoList", logoList);
			mav.setViewName("/WEB-INF/jsp/menuMgmt/logoMgmtList.jsp");
			
			log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
			log.debug(_LogPrefixStr + "|" + " LogoMgmt List-Page called !!!");
			log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		} else if (cmd.equals("detail")) {
			try {
				logoList = logoDAO.getLogoDetail(params); // 쿼리 결과
			} catch (Exception e) {
				log.error("DB 정보 획득 failed!", e);
			}

			mav.addObject("logoList", logoList);
			mav.setViewName("/WEB-INF/jsp/menuMgmt/logoMgmtDetail.jsp");
			
			log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
			log.debug(_LogPrefixStr + "|" + " LogoMgmt Detail-Page called !!!");
			log.debug(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		}
		
		return mav;
	}
	
	@RequestMapping("logoAdd.action")
	public ModelAndView logoAdd(
			HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ModelAndView mav = new ModelAndView();
		HttpSession session = request.getSession(false);
		LogoVO logoVO = new LogoVO();

		File directory = new File(savePath);
		if (!directory.isDirectory()) {
			directory.mkdirs();
		}
		
		UploadUtil.setOldFileName("");
		UploadUtil.setNewFileName("");
		
		MultipartRequest multi = new MultipartRequest(request, savePath, maxPostSize, "utf-8", new AlmapFileRenamePolicy());

		String fileOldName = UploadUtil.getOldFileName();
		String fileNewName = UploadUtil.getNewFileName();
		String fileWidth = "";
		String fileHeight = "";
		String fileThumbnailName = UploadUtil.getThumbnailFileName();

		if (UploadUtil.getNewFileName() != null && !UploadUtil.getNewFileName().isEmpty()) {
			String[] sFileName = UploadUtil.getNewFileName().split("\\|");

			for (int i = 0; i < sFileName.length; i++) {
				fileWidth = fileWidth + (i != 0 ? "|" : "") + String.valueOf(new ImageIcon(savePath + "/" + sFileName[i]).getImage().getWidth(null));
				fileHeight = fileHeight + (i != 0 ? "|" : "") + String.valueOf(new ImageIcon(savePath + "/" + sFileName[i]).getImage().getHeight(null));
				
				makeThumbnail(savePath, sFileName[i]);
			}

			if (multi.getParameter("isFileCheck") != null && !multi.getParameter("isFileCheck").isEmpty()) {
				String[] isFileCheck = multi.getParameter("isFileCheck").split("\\|");
				
				for (int i = 0; i < isFileCheck.length; i++) {
					if (isFileCheck[i].equals("0")) {
						fileOldName = fileOldName + (fileOldName != "" ? "|" : "") + multi.getParameter("logoFileOld" + (i + 1));
						fileNewName = fileNewName + (fileNewName != "" ? "|" : "") + multi.getParameter("logoFileNew" + (i + 1));
						fileThumbnailName = fileThumbnailName + (fileThumbnailName != "" ? "|" : "") + ConstCode.thumbnailPrefix + multi.getParameter("logoFileNew" + (i + 1));
					} else {
						FileUtil.pathFileDelete(savePath, multi.getParameter("logoFileNew" + (i + 1)));
						FileUtil.pathFileDelete(savePath, ConstCode.thumbnailPrefix + multi.getParameter("logoFileNew" + (i + 1)));
					}
				}
			}
		}
		
		logoVO.setLogoId(multi.getParameter("logoId"));
		logoVO.setLogoFileOld(fileOldName);
		logoVO.setLogoFileNew(fileNewName);
		logoVO.setLogoFileWidth(fileWidth);
		logoVO.setLogoFileHeight(fileHeight);
		logoVO.setLogoFileThumbnail(fileThumbnailName);
		logoVO.setUpdateUser((String)session.getAttribute("userId"));

		String isNew = multi.getParameter("isNew");
		
		try {
			sResult = (isNew.equals("Y") ? logoDAO.setLogoAdd(logoVO) : logoDAO.setLogoModify(logoVO)) > 0 ? "정상적으로 처리되었습니다." : "처리에 실패하였습니다.<BR/>관리자에게 문의하여 주십시오."; // 유저 정보 업데이트
		} catch (Exception e) {
			log.error("DB 정보 획득 failed!", e);
		}

		mav.addObject("url", "parent_loadList");
		mav.addObject("result", sResult);
		mav.addObject("act", "list");
		
		mav.setViewName("/WEB-INF/jsp/common/resultMessagePopup.jsp");
		
		return mav;
	}
	
	@RequestMapping("logoFileDownload.action")
	public void logoFileDownload(
			HttpServletRequest request, 
			HttpServletResponse response, 
			@RequestParam(value="fileName", defaultValue="") String sFileName) throws Exception {
		FileUtil.fileDownload(request, response, savePath, sFileName, sFileName);
	}
	
	public static final int RATIO = 0;
    public static final int SAME = -1;
	
	public static void makeThumbnail(
			String filePath, 
			String fileName) throws IOException {
        Image srcImg = null;
        
        File imgFile = new File(filePath + "/" + fileName);
        File outputFile = new File(filePath + "/" + ConstCode.thumbnailPrefix + fileName);
        
        String suffix = imgFile.getName().substring(imgFile.getName().lastIndexOf('.')+1).toLowerCase();
        if (suffix.equals("bmp") || suffix.equals("png") || suffix.equals("gif")) {
            srcImg = ImageIO.read(imgFile);
        } else {
            // BMP가 아닌 경우 ImageIcon을 활용해서 Image 생성
            // 이렇게 하는 이유는 getScaledInstance를 통해 구한 이미지를
        	// PixelGrabber.grabPixels로 리사이즈 할때
            // 빠르게 처리하기 위함이다.
            srcImg = new ImageIcon(filePath + "/" + fileName).getImage();
        }
        
        int srcWidth = srcImg.getWidth(null);
        int srcHeight = srcImg.getHeight(null);
        
        int destWidth = -1, destHeight = -1;
        float destRatio = (float)thumbnail_height / (float)srcHeight;
        
        if (thumbnail_height == SAME) {
            destHeight = srcHeight;
        } else if (thumbnail_height > 0) {
            destHeight = thumbnail_height;
        }
        destWidth = (int)(srcWidth * destRatio);
        
        if (thumbnail_width == RATIO && thumbnail_height == RATIO) {
            destWidth = srcWidth;
            destHeight = srcHeight;
        } else if (thumbnail_width == RATIO) {
            double ratio = ((double)destHeight) / ((double)srcHeight);
            destWidth = (int)((double)srcWidth * ratio);
        } else if (thumbnail_height == RATIO) {
            double ratio = ((double)destWidth) / ((double)srcWidth);
            destHeight = (int)((double)srcHeight * ratio);
        }
        
        Image imgTarget = srcImg.getScaledInstance(destWidth, destHeight, Image.SCALE_SMOOTH); 
        int pixels[] = new int[destWidth * destHeight]; 
        PixelGrabber pg = new PixelGrabber(imgTarget, 0, 0, destWidth, destHeight, pixels, 0, destWidth); 
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
            throw new IOException(e.getMessage());
        } 
        BufferedImage destImg = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB); 
        destImg.setRGB(0, 0, destWidth, destHeight, pixels, 0, destWidth); 
        
        ImageIO.write(destImg, "jpg", outputFile);
    }
}

